/*
 * Copyright 2009 BioTeam Inc
 * 
 * Licensed under License GNU LESSER GENERAL PUBLIC LICENSE version 3.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.bioteam.appweb.gwt.apps.server;

import java.io.FileReader;
import java.io.Reader;
import java.util.Arrays;
import java.util.Timer;

import javax.persistence.Persistence;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import net.bioteam.appweb.Config;
import net.bioteam.appweb.acd.AcdToProgram;
import net.bioteam.cloud.cluster.ClusterCleaner;
import net.bioteam.common.utils.MyEntityManager;
import net.bioteam.appweb.datatype.ParameterMapBuilder;
import net.bioteam.appweb.model.ProgramBuilder;
import net.bioteam.appweb.submit.JobCollector;
import net.sf.ehcache.CacheManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ggf.drmaa.DrmaaException;

import bsh.Interpreter;


public class MyAppInitializer implements ServletContextListener {
    public static Log log = LogFactory.getLog(
            "net.bioteam.appweb.web.MyAppInitializer");
    Timer statusChecker;
    Timer clusterCleaner;

    public void contextDestroyed(ServletContextEvent event) {
    	statusChecker.cancel();
        clusterCleaner.cancel();
    	CacheManager.getInstance().shutdown();
        MyEntityManager.emf.close();
        
        if (Config.drmmasession!=null)
        {
        	try {
				Config.drmmasession.exit();
			} catch (DrmaaException e) {
				
				e.printStackTrace();
			}
        }
    }

    public void contextInitialized(ServletContextEvent event) {
    	String topdir=event.getServletContext().getInitParameter("CMD_TOP_DIR");
    	Config.topdir=topdir;
        CacheManager.create();

        String[] cacheNames = CacheManager.getInstance().getCacheNames();
        log.debug("cache initialized " + Arrays.toString(cacheNames));

        ProgramBuilder.cache = CacheManager.getInstance().getCache("programs");

//        ScriptEngineManager manager = new ScriptEngineManager();
//        ScriptEngine engine = manager.getEngineByName("javascript");
//        InputStream in = Thread.currentThread().getContextClassLoader()
//                               .getResourceAsStream("config.js");
//        InputStreamReader reader = new InputStreamReader(in);
//
//        try {
//            engine.eval(reader);
//        } catch (ScriptException e) {
//            throw new RuntimeException(e);
//        }

        Interpreter bsh = new Interpreter(); // Construct an interpreter
		
        try
        {
			ClassLoader tcl = Thread.currentThread().getContextClassLoader();
		    bsh.getClassManager().setClassLoader(tcl);
		    Reader reader=new FileReader(topdir+"/conf/config.bsh");
			bsh.eval(reader);
			//log.info("bsh is evaluated");
			MyEntityManager.emf = Persistence.createEntityManagerFactory("appweb");
			Config.init();
        } catch (Exception e)
        {
        	throw new RuntimeException(e);
        }
		 
        //thread to check job
        statusChecker= new Timer("statusChecker", true);
        statusChecker.schedule(new JobCollector(), JobCollector.interval, JobCollector.interval);
        
        //thread to clean cluster.
        clusterCleaner=new Timer("clusterCleaner", true);
        clusterCleaner.schedule(new ClusterCleaner(), ClusterCleaner.interval, ClusterCleaner.interval);
        
        //a separate thread to initialize this
        new ProgramInitializer().start();
    }
}

class ProgramInitializer extends Thread
{

	@Override
	public void run() {
		 /**
         * Slow the first time. However solve the synchronization issue
         */
		try {
			AcdToProgram.init();
			 ProgramBuilder.getProgramCategory();
			 
			 ParameterMapBuilder.init();
		} catch (Exception e) {
			//TODO log this
			throw new RuntimeException(e);
		}
		
	}
	
	
}
